package main

import (
	"fmt"
	"log"
	"test/geeCache/day02/geecache"
	"unsafe"
)

var db = map[string]string{
	"Tom":  "630",
	"Jack": "589",
	"Sam":  "567",
}

func main() {

	test()

}

func test() {
	loadCounts := make(map[string]int, len(db))

	gee := geecache.NewGroup("scores", 2<<10, geecache.GetterFunc(
		func(key string) ([]byte, error) {
			log.Println("[slow db] search key", key)

			if v, ok := db[key]; ok {
				if _, ok := loadCounts[key]; !ok {
					loadCounts[key] = 0
				}
				loadCounts[key] += 1
				return []byte(v), nil
			}
			return nil, fmt.Errorf("%s not exist", key)
		}))

	for k, _ := range db {
		view, err := gee.Get(k)
		if err != nil {
			fmt.Println("failed to get value of Tom")
		}
		fmt.Printf("key[%s] view is %s \n", k, view.String())
		// cache hit
		view, err = gee.Get(k)
		if err != nil || loadCounts[k] > 1 {
			fmt.Printf("cache %s miss\n", k)
		}
		fmt.Printf("key[%s] view is %s \n", k, view.String())

		p := unsafe.Pointer(&view)
		offset := uintptr(0)
		ptr2x := (*[]byte)(unsafe.Pointer(uintptr(p) + offset))

		(*ptr2x)[0] = 'x'
		fmt.Println("==>", *ptr2x)

		view, err = gee.Get(k)
		if err != nil || loadCounts[k] > 1 {
			fmt.Printf("cache %s miss\n", k)
		}
		fmt.Printf("key[%s] view is %s \n", k, view.String())
	}

	if view, err := gee.Get("unknown"); err == nil {
		fmt.Printf("the value of unknown should be empty, but %s get", view)
	}
}
